//
//  AsNetworkClient.m
//  shopcity
//
//  Created by huangbenhua on 15-3-11.
//  Copyright (c) 2015年 laohuang. All rights reserved.
//

#import "JKHttpClient.h"
#import "AFHTTPRequestOperation.h"
#import "AFHTTPRequestOperationManager.h"
#import "SNPleaseLogInAlertView.h"
#import "MyToast.h"
#import "MBProgressHUD+Conveniently.h"


static const CGFloat kToastShowDuration = 2.0f;

@interface JKHttpClient()<UIAlertViewDelegate>

@property (strong, nonatomic) AFHTTPRequestOperationManager* requestManager;
@property (strong, nonatomic) AFNetworkReachabilityManager *reachabilityManager;

@property (assign, nonatomic,getter=isShowNewWorkErrorToast) BOOL showNewWorkErrorToast;
@property (assign, nonatomic,getter=isShowMask) BOOL showMask;

@property (strong, nonatomic) NSString *maskTitle;

@property (assign, nonatomic) long cancelAllStamp;

@end


@implementation JKHttpClient

@synthesize requestManager = _requestManager;
@synthesize reachabilityManager = _reachabilityManager;

-(instancetype)init
{
    self = [super init];
    if (self) {
        _requestManager = [[AFHTTPRequestOperationManager alloc] initWithBaseURL:nil];
        //因为后台回包的MIMEType不为text/json，导致会被AFJSONResponseSerializer拒绝，所以使用AFHTTPResponseSerializer
        
        _requestManager.responseSerializer = [AFHTTPResponseSerializer serializer];
        //检查网络状态
        _reachabilityManager = [AFNetworkReachabilityManager sharedManager];
        _showMask = NO;
        _showNewWorkErrorToast = NO;
        _maskTitle = @"";
    }
    return self;
}

- (void)showNetUnReachableToast{
    self.showNewWorkErrorToast = YES;
}
- (void)showMaskWithMessage:(NSString *)message{
    self.showMask = YES;
    self.maskTitle = message;
}

- (void)maskAndToastDefaultReset{
    _showMask = NO;
    _showNewWorkErrorToast = NO;
    _maskTitle = @"";
    [MBProgressHUD dismissMBProgressHUBOnWindows];
}

-(BOOL)isOffline:(JKResponse*)resp
{
    if (resp.status != JKResponseOffline) {
        return NO;
    }

    [SNPleaseLogInAlertView pleaseLogIn];
    
    return YES;
}

- (BOOL)checkToastAndMask{
    if (self.isShowNewWorkErrorToast) {
        if (!self.reachabilityManager.isReachable) {
            [MyToast showWithText:kMallReminderNewWorkUnReachable bottomOffset:[UBO_WINDOW uy:120] duration:kToastShowDuration];
        }
    }
    
    if (self.isShowMask) {
        if (self.reachabilityManager.isReachable) {
            [MBProgressHUD showMBProgressHUBOnWindowsWithMessage:self.maskTitle];
        }else{
            return YES;
        }
    }
    return NO;
}

-(id)upload:(NSString*)path
       data:(NSData*)data
     params:(NSDictionary*)params
     result:(void(^)(JKResponse* resp))result
{
    if ([self checkToastAndMask]) {
        return nil;
    }
    
    if (path == nil) {
        path = @"";
    }

    
    long stamp = self.cancelAllStamp;
    if (!params) {
        params = @{};
    }
    NSString* name = [NSMassKit objectFrom:params ofKey:kUploadParamName nilValue:@"data"];
    NSString* file = [NSMassKit objectFrom:params ofKey:kUploadParamFileName nilValue:@"uploadFile"];
    NSString* type = [NSMassKit objectFrom:params ofKey:kUploadParamMimeType nilValue:@"application/octet-stream"];
    
    return [_requestManager POST:path parameters:params
       constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
           [formData appendPartWithFileData:data
                                       name:name
                                   fileName:file
                                   mimeType:type];
       } success:^(AFHTTPRequestOperation *operation, id responseObject) {
           
           [self maskAndToastDefaultReset];
           
           if (self.cancelAllStamp != stamp) {
               return;
           }
           if (result) {
               JKResponse* rt = [[JKResponse alloc] initWithResponse:operation.response req:operation.request data:responseObject];
               if (![self isOffline:rt]) {
                   result(rt);
               }
               
           }
       } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
           
           [self maskAndToastDefaultReset];
           
           if (self.cancelAllStamp != stamp) {
               return;
           }
           if (result) {
               JKResponse* rt = [[JKResponse alloc] initWithError:error req:operation.request];
               result(rt);
           }
       }];
};

-(id)post:(NSString*)path
   params:(id)params
   result:(void(^)(JKResponse* resp))result
{
    if ([self checkToastAndMask]) {
        return nil;
    }
    
    long stamp = self.cancelAllStamp;
    
    
    NSArray * pathAndParams = [self urlPathAndParmasWithPath:path params:params];
    
    DLog(@"%@  %@",[pathAndParams firstObject],[pathAndParams lastObject]);
    return [_requestManager POST:[pathAndParams firstObject] parameters:[pathAndParams lastObject]
                         success:^(AFHTTPRequestOperation *operation, id responseObject) {
                             
                             [self maskAndToastDefaultReset];
                             
                             if (self.cancelAllStamp != stamp) {
                                 return;
                             }
                             if (result) {
                                 JKResponse* rt = [[JKResponse alloc] initWithResponse:operation.response req:operation.request data:responseObject];
                                 if (![self isOffline:rt]) {
                                     result(rt);
                                 }
                             }
                         }
                         failure:^(AFHTTPRequestOperation *operation, NSError *error) {
                             
                             [self maskAndToastDefaultReset];
                             
                             if (self.cancelAllStamp != stamp) {
                                 return;
                             }
                             if (result) {
                                 JKResponse* rt = [[JKResponse alloc] initWithError:error req:operation.request];
                                 result(rt);
                             }
                         }];
};

- (NSArray *)urlPathAndParmasWithPath:(NSString *)path params:(id)params
{
    NSDictionary * LastParams = @{};
    NSString * lastPath = path?path:@"";
    
    if (params) {
        
        NSMutableString * multablePath = [NSMutableString stringWithString:lastPath];
        
        if ([[params class] isSubclassOfClass:[NSDictionary class]]) {
            LastParams = params ;
        } else if ([[params class] isSubclassOfClass:[NSArray class]]) {
            NSString * staticParmas = [params componentsJoinedByString:@"/"];
            
            if ([[path substringWithRange:NSMakeRange(path.length-1, 1)] isEqualToString:@"/"]) {
                [multablePath appendString:staticParmas];
            } else {
                [multablePath appendFormat:@"/%@",staticParmas];
            }
            
            lastPath = multablePath;
        } else {
//            if ([[params substringWithRange:NSMakeRange(0, 1)] isEqualToString:@"?"]) {
//                [multablePath appendString:params];
//            } else {
//                [multablePath appendFormat:@"?%@",params];
//            }
            [multablePath appendString:params];
            lastPath = multablePath;
        }
        
    }
    
    return @[lastPath,LastParams];
}

-(id)get:(NSString*)path
  params:(id)params
  result:(void(^)(JKResponse* resp))result
{
    
    if ([self checkToastAndMask]) {
        return nil;
    }
    
    long stamp = self.cancelAllStamp;
    
    NSArray * pathAndParams = [self urlPathAndParmasWithPath:path params:params];

    return [_requestManager GET:[pathAndParams firstObject] parameters:[pathAndParams lastObject]
                        success:^(AFHTTPRequestOperation *operation, id responseObject) {
                        
                            [self maskAndToastDefaultReset];
                            
                            if (self.cancelAllStamp != stamp) {
                                return;
                            }
                             if (result) {
                                 JKResponse* rt = [[JKResponse alloc] initWithResponse:operation.response req:operation.request data:responseObject];
                                 
                                 if (![self isOffline:rt]) {
                                     
                                     result(rt);
                                 }
                             }
                         }
                        failure:^(AFHTTPRequestOperation *operation, NSError *error) {
                            
                            [self maskAndToastDefaultReset];
                            
                            if (self.cancelAllStamp != stamp) {
                                return;
                            }
                             if (result) {
                                 JKResponse* rt = [[JKResponse alloc] initWithError:error req:operation.request];
                                 result(rt);
                             }
                         }];
};

-(id)get:(NSString*)path
  result:(void(^)(JKResponse* resp))result
{
//    if (path == nil) {
//        return nil;
//    }
    return [self get:path params:nil result:result];
};

-(BOOL)isRunning
{
    for (NSOperation *operation in [_requestManager.operationQueue operations]) {
        if (![operation isFinished] && ![operation isCancelled]) {
            return YES;
        }
    }
    return NO;
}

-(void)cancelAll
{
    @synchronized(self){
        self.cancelAllStamp ++;
        [_requestManager.operationQueue cancelAllOperations];
    }
};

-(BOOL)cancel:(NSString*)path
{
    BOOL found = NO;
    for (NSOperation *operation in [_requestManager.operationQueue operations]) {
        if (![operation isKindOfClass:[AFHTTPRequestOperation class]]) {
            continue;
        }
        AFHTTPRequestOperation* req = (AFHTTPRequestOperation *)operation;
        NSRange range = [[[[req request] URL] path] rangeOfString:path];
        if (range.location == 0) {
            [operation cancel]; 
            found = YES;
        }
    }
    return found;
};

-(BOOL)close:(id)handler
{
    if (handler) {
        NSOperation* op = (NSOperation*)handler;
        if (!op.cancelled) {
            [op cancel];
        }
        return YES;
    }
    return NO;
};

-(void)dealloc
{
    [self cancelAll];
}

@end
